# JSON libraries
library(rjson)
library(RJSONIO)
library(jsonlite)
# To read the netCDF file (check for better options!)
library(ncdf4)
# To get the min bounding box
library(sp)
library(shotGroups)
# To plot the track of the glider
library(spacetime)
library(trajectories)
library(leaflet)
# To format dates
library(lubridate)
# ?? Not sure why I was using this
library(tidyverse)
# to format text in the console (does not format text in R markdown)
require(crayon)
The following function gets the time dimension from the glider netCDF file and converts it from double to Unix time. The fucnction also extracts the time stamp and the date as well. This function returns a dataframe that has the formatted time in addition the timestamp and the date. This function takes an ncdf4 object as an argument.
formatTimeDim <- function(file){
tryCatch(
expr = {
# Getting the time dimension
time = file$dim$TIME
# Formatting time
time_formatted = as.POSIXct(time$vals, origin="1970-01-01")
# Extracting the time stamp from the unix time object
timeStamp = format(time_formatted,'%H:%M:%S')
# Extracting the date from the unix time object
date = as.Date(time_formatted)
# Combining the formatted time, the time stamp and the date in one data frame
all = cbind.data.frame(time_formatted, timeStamp, date)
message('The time dimension has been successfully formatted!')
# returning the dataframe
return(all)
},
error = function(e){
message('Caught an error!')
print(e)
},
warning = function(w){
message('Caught an warning!')
print(w)
}
)
}
This function should return a dataframe that has the lat, lon, the time formatted, time stamp and date with no NA data.
combineLatLongWithTime <- function(filePath){
tryCatch(
expr = {
# Reading the file
file = nc_open(filePath)
# Getting the latitude and longitude
lon = ncvar_get(file,"LONGITUDE")
lat = ncvar_get(file,"LATITUDE")
# Calling the time function to get the dataframe that has the time formatted
time = formatTimeDim(file)
# Combining the time data frame with lat and long. This dataframe has NA values
dataframe = cbind.data.frame(lat, lon, time)
cat(bold("The number of NA this file has is: ", sum(is.na(dataframe))))
cat("\n")
# removing NA values
dataframe_No_NA = dataframe %>% drop_na()
return(dataframe_No_NA)
message("dataframe successfully created!")
},
error = function(e){
message('Caught an error!')
print(e)
},
warning = function(w){
message('Caught an warning!')
print(w)
}
)
}
This function takes the a datafram that has lat, lon, time_formatted, time stamp and date as an argument. This is the output of the function combineLatLongWithTime I am not sure how to select the first tow colomns of the dataframe that has lat, lon, time…… is it better if I put lat,lon in a seperate dataframe???? It looks to me that lat_lon_time_No_NA %>% select(1:2) makes things more complicated!!!
plotMissionTrack = function(lat_lon_time_No_NA){
# Setting a projection
crs = CRS("+proj=longlat +datum=WGS84")
# Creating an STIDF object
stidf = STIDF(SpatialPoints(lat_lon_time_No_NA %>% select(1:2),crs), lat_lon_time_No_NA$time_formatted, data.frame(lat_lon_time_No_NA %>% select(1:2)))
# Creating a track object
glider_track = Track(stidf)
# plotting the map
return(leaflet() %>%addTiles() %>% addPolylines(lat = glider_track@data[,1], lng = glider_track@data[,2]))
}
This function also takes a dataframe that has lat, lon, time_fomratted, timestamp and date as an input. This is the output of the function combineLatLongWithTime.
getMissionTrackLabels = function(lat_lon_time_No_NA){
# Splitting the dataframe based on date
# This results in a list of dataframes
list = split(lat_lon_time_No_NA, lat_lon_time_No_NA$date)
#This provides the first row of each day in the data frame
first_days = do.call(rbind, (lapply(list, function(x) x[1,])))
return(first_days)
}
I’m still thinking of plotting the first value of the mission in green and the last value in red. I think this requiers extracting the first vlaue in a seperate list or a dataframe and the same for the last value and then add them to the plotting function.
plotMissionTrackWithLabels = function(lat_lon_time_No_NA){
track = plotMissionTrack(lat_lon_time_No_NA)
first_days = getMissionTrackLabels(lat_lon_time_No_NA)
return (track %>% addAwesomeMarkers(data = first_days, lat = ~first_days$lat, lng = ~first_days$lon, label = first_days$time_formatted))
}
# This is where the netCDF data files reside
netCDF_Data_Files_Path = "D:/University/WWU/WWU 5/netCDF sample files/"
netCDF_File2_Name = "sg558_fram_jun2013_R.nc"
# This is the files that needs to be read
netCDF_File1_Name = "wallis_mooset01_R.nc"
# This is the complete path to the netCDF file that is being read
file_Path_File1 = paste0(netCDF_Data_Files_Path,netCDF_File1_Name)
lat_lon_time_No_NA_File1 = combineLatLongWithTime(file_Path_File1)
## The time dimension has been successfully formatted!
## The number of NA this file has is: 464
plotMissionTrack(lat_lon_time_No_NA_File1)
x = getMissionTrackLabels(lat_lon_time_No_NA_File1)
plotMissionTrackWithLabels(lat_lon_time_No_NA_File1)
# Converting the dataframe to a SpatialPoints object
lat_lon_spatial_file1 = SpatialPoints(lat_lon_time_No_NA_File1 %>% select(1:2))
# Applying the bbox function
bb_sp = bbox(lat_lon_spatial_file1)
head(lat_lon_spatial_file1)
## SpatialPoints:
## lat lon
## [1,] 43.00009 5.993153
## [2,] 43.00021 5.992803
## [3,] 43.00055 5.992498
## [4,] 43.00055 5.992292
## [5,] 43.00059 5.992281
## [6,] 43.00063 5.992271
## Coordinate Reference System (CRS) arguments: NA
bb_sp
## min max
## lat 41.674347 43.00926
## lon 5.399076 7.16478
This function also returns the width and height of the bounding box. Since the projection is WGS84. This information is not useful.
lat_lon = lat_lon_time_No_NA_File1 %>% select(1:2)
names(lat_lon)[1] = "point.x"
names(lat_lon)[2] = "point.y"
bb = getBoundingBox(lat_lon)
bb
## $pts
## xleft ybottom xright ytop
## 41.674347 5.399076 43.009263 7.164780
##
## $width
## [1] 1.334915
##
## $height
## [1] 1.765704
##
## $FoM
## [1] 1.55031
##
## $diag
## [1] 2.213529
What I thought of is splitting the dataframe that has all the days in the netCDF file into seperate dataframes each containing the measurement for each day. The first row of each dataframe is then extracted to get the first measurement of that day.
# Splitting the dataframe based on date
# This results in a list of dataframes
#list = split(lat_lon_time_No_NA, lat_lon_time_No_NA$date)
#This provides the first row of each day in the data frame
#first_days = do.call(rbind, (lapply(list, function(x) x[1,])))
# Plotting the glider track with labels
#leaflet() %>%addTiles() %>% addPolylines(lat = glider_track@data[,1], lng = glider_track@data[,2]) %>% addAwesomeMarkers(data = first_days, lat = ~first_days$lat, lng = ~first_days$lon, label = first_days$time_formatted)
# Getting the last day
#last_day_df = as.data.frame(tail(list, n = 1))
# Setting the name of the columns to the same names of the first_days dataframe
# This makes it easier to combine both dataframes
#names(last_day_df) = colnames(first_days)
#last_day = tail(last_day_df, n=1)
#Adding the last value of the last day to the first_days dataframe
#first_days_plus_last_value = rbind(first_days, last_day)
# Plotting the glider track with labels including the last vlaue of the last day
#leaflet() %>%addTiles() %>% addPolylines(lat = glider_track@data[,1], lng = glider_track@data[,2]) %>% addMarkers(data = first_days_plus_last_value, lat = ~first_days_plus_last_value$lat, lng = ~first_days_plus_last_value$lon, label = first_days_plus_last_value$time_D_formatted)
# This provides a summary of the dataframe based on the date
#lat_lon_time_dateframe %>% group_split(date) %>% map(summary)